#include "MyRpc.h"
#include "TestMyRpc.pb.h"
#include <string>
#include <vector>

// 字符串反转函数
void LocalReverseStr(std::string &str)
{
    int size = str.size();
    for (int i = 0; i < size / 2; i++)
    {
        char temp = str[i];
        str[i] = str[size - i - 1];
        str[size - i - 1] = temp;
    }
}

class ReverseStrService : public test::ReverseStrService
{
public:
    void ReverseStr(::google::protobuf::RpcController *controller,
                    const ::test::ReverseStrRequest *request,
                    ::test::ReverseStrResponse *response,
                    ::google::protobuf::Closure *done)
    {
        std::string str = request->str();
        LocalReverseStr(str);
        response->set_reversed_str(str);
        done->Run();
    }
};

// 数字查找函数
int LocalFindNum(std::vector<int> &nums, int target) 
{
    // 二分查找
    int left = 0, right = nums.size() - 1;
    while(left <= right) 
    {
        int mid = left + (right - left) / 2;
        if(nums[mid] == target) 
            return mid;
        else if(nums[mid] < target)
            left = mid + 1;
        else if(nums[mid] > target)
            right = mid - 1;
    }
    return -1;
}

class FindNumService : public test::FindNumService
{
public:
    void FindNum(::google::protobuf::RpcController *controller,
                 const ::test::FindNumRequest *request,
                 ::test::FindNumResponse *response,
                 ::google::protobuf::Closure *done)
    {
        std::vector<int> nums(request->nums().begin(), request->nums().end());
        int target = request->target();
        int index = LocalFindNum(nums, target);
        response->set_index(index);
        done->Run();
    }
};

// 登录函数
struct User
{
    uint64_t id;
    std::string name;
    std::string password;
    // 联系方式
    struct Contact
    {
        uint64_t phone;
        std::string email;
    };
    Contact contact;
};
bool LocalLogin(User &user)
{
    std::string name = "zhang san", password = "123456";
    if(user.name == name && user.password == password)
        return true;
    return false;
}

class LoginService : public test::LoginService
{
public:
    void Login(::google::protobuf::RpcController *controller,
               const ::test::LoginRequest *request,
               ::test::LoginResponse *response,
               ::google::protobuf::Closure *done)
    {
        User user;
        user.id = request->id();
        user.name = request->username();
        user.password = request->password();
        user.contact.phone = request->contact().phone();
        user.contact.email = request->contact().email();
        bool success = LocalLogin(user);
        response->set_success(success);
        done->Run();
    }

};

int main(int argc, char **argv)
{
    MyRpc::Init(argc, argv);

    RpcServer RpcServer;
    RpcServer.NotifyService(new ReverseStrService());
    RpcServer.NotifyService(new FindNumService());
    RpcServer.NotifyService(new LoginService());
    RpcServer.Run();

    return 0;
}